﻿using UnityEngine;
using System.Collections.Generic;

public class SpawnPool
{
	#region SpawnPool class definition
	Dictionary<string, SpawnPool> mSpawnPools = new Dictionary<string, SpawnPool>();
	
	public SpawnPool CreateSpawnPool(string poolId)
	{
		SpawnPool pool = GetSpawnPool(poolId) as SpawnPool;
        if (null == pool)
        {
			pool = new SpawnPool();
			mSpawnPools[poolId] = pool as  SpawnPool;
        }

        return pool;
	}	

	public  SpawnPool RemovePool(string poolId)
	{
		SpawnPool pool = null;
	    if (mSpawnPools.ContainsKey(poolId))
	    {
	        pool = mSpawnPools[poolId];
	        mSpawnPools.Remove(poolId);
	    }
	    else
	    {
	        Debug.LogWarning("移除操作未进行。尝试移除不存在的Pool：" + poolId);
	    }

	    return pool;
	}

	public  SpawnPool GetSpawnPool(string poolId)
	{
	    if (mSpawnPools.ContainsKey(poolId))
	    {
			return mSpawnPools[poolId] as SpawnPool;
	    }

	    return null;
	}
	#endregion

	private static readonly string ON_SPAWN_MESSAGE = "OnSpawn";
	private static readonly string ON_DESPAWN_MESSAGE = "OnDespawn";

	#region SpawnPool class definition
	
	private List<PrefabPool> mPrefabPoolList;
	
	public SpawnPool()
	{
	    Clear();
	}

	public void Clear()
	{
	    if (null != mPrefabPoolList)
	    {
	        foreach (PrefabPool pool in mPrefabPoolList)
	        {
	            if (null != pool)
	            {
	                pool.Clear();
	            }
	        }
	    }
	    mPrefabPoolList = new List<PrefabPool>();
	}

	private UnityEngine.Object SpawnWorker(UnityEngine.Object prefab)
	{
	    UnityEngine.Object ret = null;

	    if (null != prefab)
	    {
	        PrefabPool prefabPool = null;
	        foreach (PrefabPool pool in mPrefabPoolList)
	        {
	            if (pool.GetPrefab().Equals(prefab))
	            {
	                prefabPool = pool;
	                break;
	            }
	        }

	        if (null == prefabPool)
	        {
	            prefabPool = new PrefabPool(prefab);
	            mPrefabPoolList.Add(prefabPool);
	        }

	        ret = prefabPool.Spawn();
	    }

	    return ret;
	}

    public bool Initialize(UnityEngine.Object prefab,int nCount)
    {
	    List<UnityEngine.Object> spawnedList = new List<UnityEngine.Object>();

	    for(int i=0;i<nCount;i++)
		{
		    spawnedList.Add(Spawn(prefab));
		} 
	    foreach (UnityEngine.Object obj in spawnedList)
		{
		    Despawn(obj);
		    
		}
	    spawnedList.Clear();
	    return true;
	}
	
	public UnityEngine.Object Spawn(UnityEngine.Object prefab)
	{
		return Spawn (prefab, Vector3.zero, Quaternion.identity);
	}

	public UnityEngine.Object Spawn(UnityEngine.Object prefab, Vector3 position, Quaternion rotation)
	{
		return Spawn(prefab, position, rotation, null);
	}

	public UnityEngine.Object Spawn(UnityEngine.Object prefab, Vector3 position, Quaternion rotation, Transform parent)
	{
	    UnityEngine.Object ret = null;

	    if (null != prefab)
	    {
	        ret = SpawnWorker(prefab);

	        GameObject go = ret as GameObject;

			if(go==null)
			{
				Transform trans= ret as Transform;
				if(null!=trans)
				{
					go=trans.gameObject;
				}
			}

	        if (null != go)
	        {
	            go.SetActive(true);
	            if (null != go.transform)
	            {
	                go.transform.position = position;
	                go.transform.rotation = rotation;
	                go.transform.parent = parent;
	            }
	            go.BroadcastMessage(ON_SPAWN_MESSAGE, SendMessageOptions.DontRequireReceiver);
	        }
	    }
	    else
	    {
	        Debug.LogWarning("无法Spawn。因为传入prefab为null。");
	    }

	    return ret;
	}
	
	public bool Despawn(UnityEngine.Object obj)
	{
		DebugUtil.Assert(obj != null, "Despawned obj should not be null");
		if (obj == null)
			return false;

        PrefabPool foundPool = null;
        foreach(PrefabPool onePool in mPrefabPoolList)
        {
            if(onePool.IsObjectSpawnedFromPool(obj))
            {
                foundPool = onePool;
                break;
            }
        }

		DebugUtil.Assert(foundPool != null);
        if(null == foundPool)
        {
            Debug.LogWarning("无法Despawn。因为传入的对象" + obj.ToString() +
                "并非从SpawnPool" + ToString() + "产生。");
            return false;
        }

        foundPool.Despawn(obj);

        UnityEngine.GameObject go = obj as UnityEngine.GameObject;

		 if(go==null)
		 {
			Transform trans= obj as Transform;
			if(null!=trans)
			{
				go=trans.gameObject;
			}
		}

        if (null != go)
        {
            go.BroadcastMessage(ON_DESPAWN_MESSAGE, SendMessageOptions.DontRequireReceiver);
            go.SetActive(false);
        }

        return true;
	}
	#endregion
}


 